﻿using System;
using System.ComponentModel;
using System.Reflection;

namespace SDL
{
	public static class ObjectExtension
	{
		public static object GetField(this object oObj, string sName)
		{
			var type = oObj.GetType();

			var ret = type.InvokeMember(sName,
										BindingFlags.Instance |
										BindingFlags.Public |
										BindingFlags.GetProperty,
										null, oObj, new object[] { });
			return (ret);
		}

		public static void SetField(this object oObj, string sName, object[] args)
		{
			var type = oObj.GetType();
			try
			{
				type.InvokeMember(sName,
								  BindingFlags.Instance |
								  BindingFlags.Public |
								  BindingFlags.SetProperty,
								  null, oObj, args);
			}
			catch
			{ }
		}

		public static bool IsAttributed(this object oObj, Type type)
		{
			return (oObj.GetType().GetCustomAttributes(type, false).Length > 0);
		}

		public static object GetAttribute(this object oObj, Type type)
		{
			var attrs = oObj.GetType().GetCustomAttributes(type, true);
			return (attrs.Length == 0 ? null : attrs[0]);
		}

		public static bool IsCachable(this object oObj)
		{
			return (oObj.IsAttributed(typeof(CachableAttribute)));
		}

		public static string GetDescription(this Enum value)
		{
			var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
			return (attributes.Length > 0) ? attributes[0].Description : string.Empty;
		}

		public static string GetPropertyDescription(this Type value, string Property)
		{
			var attributes = (DescriptionAttribute[])value.GetProperty(Property).GetCustomAttributes(typeof(DescriptionAttribute), false);
			return (attributes.Length > 0) ? attributes[0].Description : string.Empty;
		}

		public static string GetDescription(this object value)
		{
			var attributes = (DescriptionAttribute[])value.GetType().GetCustomAttributes(typeof(DescriptionAttribute), false);
			return (attributes.Length > 0) ? attributes[0].Description : string.Empty;
		}
	}
}
